﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using KinectTD.Towers;
using KinectTD.Input;
namespace KinectTD.MapControl
{
    public class Map
    {

        #region Static Members
        private static Random mapGenerator = new Random();
        #endregion

        #region Textures
        private Texture2D forestGrass;
        private Texture2D forestBase;
        private Texture2D landShader;
        private Texture2D landBase;

        private List<Texture2D> treeTextures;
        #endregion

        #region Members
        private Rectangle drawRect;

        private int forestWidth;
        private int forestHeight;

        private int width { get { return drawRect.Width; } }
        private int height { get { return drawRect.Height; } }
        private int x { get { return drawRect.X; } }
        private int y { get { return drawRect.Y; } }
        #endregion

        #region Towers - OH GOD TOWERS
        public List<Tower> placedTowers;
        //Used for kinect clicking behaviour
        private Point previousPosition;
        private Vector3 previousLeftHand;
        public delegate void ClickedEventHandler(object sender, KinectClickArgs a);
        public event ClickedEventHandler Clicked;

        #endregion

        private List<Vector2> groundPosition;
        private List<Vector2> forestPlacement;
        private List<TreePlacement> treeLocs;

        public Rectangle DrawRect
        {
            get { return drawRect; }
        }

        public Map(Rectangle targetRect)
        {

            drawRect = targetRect;

            groundPosition = new List<Vector2>();
            forestPlacement = new List<Vector2>();
            treeLocs = new List<TreePlacement>();
            treeTextures = new List<Texture2D>();

            placedTowers = new List<Tower>();
        }



        public void LoadContent(ContentManager Content)
        {

            landBase = Content.Load<Texture2D>("Map/landMid");
            landShader = Content.Load<Texture2D>("Map/normalLand");
            forestGrass = Content.Load<Texture2D>("Map/forestLand");
            forestBase = Content.Load<Texture2D>("Map/forestBase");

            foreach (string s in Engine.assetNames("Content/Map/Trees"))
            {
                treeTextures.Add(Content.Load<Texture2D>("Map/Trees/" + s));
            }


            //Scale down to a fifth of the map size
            forestWidth = (int)(width * 0.2f);
            forestHeight = (int)(height * 0.2f);

            GenerateMap();
        }

        private void GenerateMap()
        {

            for (int i = 0; i < width / 10; ++i)
            {
                groundPosition.Add(new Vector2(mapGenerator.Next(width), mapGenerator.Next(height)));
            }

            for (int i = 0; i < 15; ++i)
            {
                int type = mapGenerator.Next(3);
                if (type == 1)
                {
                    Vector2 forestPos = new Vector2(mapGenerator.Next(width), mapGenerator.Next(height));
                    int treeCount = mapGenerator.Next(5, 15);
                    for (int j = 0; j < treeCount; ++j)
                    {
                        TreePlacement t = new TreePlacement();
                        t.tex = treeTextures[mapGenerator.Next(treeTextures.Count - 1)];
                        int xPos = mapGenerator.Next((int)forestPos.X + 40, ((int)forestPos.X + forestWidth) - 80);
                        int yPos = mapGenerator.Next((int)forestPos.Y + 40, ((int)forestPos.Y + forestHeight) - 80);
                        t.drawRect = new Rectangle(xPos + x, yPos + y, (int)(t.tex.Width * 0.2f), (int)(t.tex.Height * 0.2f));

                        treeLocs.Add(t);
                    }
                    forestPlacement.Add(forestPos);
                }
            }
            treeLocs.Sort();
            /*
             * TODO: Generate a map of any size (can be scaled for the window)
             * Randomly place land blocks to create a kind of land feel
             * Determine how much (if any) of the land should be built up of forest blocks
             * Add some trees to the forest blocks (and some smaller trees to the non-forest blocks)
             * Work out a path
             * Add some waves to the water if their is space
             * 
             */
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(landBase, new Rectangle(-300, -300, width * 2, height * 2), Color.White);
            spriteBatch.Draw(landShader, new Rectangle(-300, -300, width * 2, height * 2), Color.White);

            foreach (Vector2 v in forestPlacement)
            {
                Rectangle forestRect = new Rectangle((int)v.X + x, (int)v.Y + y, forestWidth, forestHeight);
                spriteBatch.Draw(forestGrass, forestRect, Color.White);

            }
            foreach (TreePlacement t in treeLocs)
            {
                spriteBatch.Draw(t.tex, t.drawRect, Color.White);
            }


            foreach (Tower t in placedTowers)
                t.Draw(spriteBatch);

        }

        public void Update(GameTime gameTime)
        {
            if (drawRect.Contains(Kinect.CursorPosition))
            {
                Point currentPosition = Kinect.CursorPosition;
                Vector3 leftHandPosition = Kinect.LeftHandPosition;
                int movement = 100;
                Rectangle boundary = new Rectangle((int)previousPosition.X - movement, (int)previousPosition.Y - movement, (int)previousPosition.X + movement * 2, (int)previousPosition.Y + movement * 2);

                if ((int)leftHandPosition.Y < currentPosition.Y)
                {
                    if (Clicked != null)
                    {

                        Clicked(this, new KinectClickArgs(currentPosition));
                    }
                }
                //if (MouseHelper.MouseLeftPressed)
                //{
                //    if (Clicked != null)
                //    {

                //        Clicked(this, new KinectClickArgs(MouseHelper.MousePosition));
                //    }
                //}



                previousPosition = currentPosition;
                previousLeftHand = leftHandPosition;
            }



            foreach (Tower t in placedTowers)
                t.Update(gameTime);
        }
    }

    internal struct TreePlacement : IComparable
    {
        public Texture2D tex;
        public Rectangle drawRect;

        public int CompareTo(object obj)
        {
            TreePlacement comp = (TreePlacement)obj;
            Rectangle compareRect = drawRect;
            compareRect.Y = drawRect.Height / 2;
            if (compareRect.Intersects(comp.drawRect))
            {
                return 1;
            }
            return 0;
        }
    }

    public class KinectClickArgs : EventArgs
    {
        public Point position;

        public KinectClickArgs(Point pos)
        {
            position = pos;
        }
    }
}
